/*lic*/
#ifndef __FLASH_MODULE_H__
#define __FLASH_MODULE_H__

#include "main.h"
#include "SpiInitHelper.h"

#define FLASH_WRITEABLE (1 << 0)
#define FLASH_CS_EN (1 << 1)

typedef struct __Tag_Flash_Def {
	uint8_t flash_status;
	uint8_t cs_port;
	uint16_t cs_pin;
	uint8_t sr1;
	uint8_t sr2;
	uint8_t sr3;
	struct rt_mutex flash_busy;
	Spi_Transport_Def* spi_obj;
}Flash_Def;

extern Flash_Def flash1_obj;

rt_err_t W25q_Init(void);
// 关闭写保护。注意，执行写入和擦除命令后写保护会被自动打开
rt_err_t W25q_Write_enable(Flash_Def* obj);
// 打开写保护
rt_err_t W25q_Write_disable(Flash_Def* obj);
// 硬件控制写保护。仅限于标志位的写保护
rt_err_t W25q_Write_Hw_Enable(Flash_Def *obj);
// 擦除1K的页面,非对齐操作，不建议使用
rt_err_t W25q_Erase_1K(Flash_Def* obj, uint64_t page_addr);
// 读取任意地址，注意自己把握不要跨页。每页256字节，也就是0x100, 读取无所谓
rt_err_t W25q_Read_page(Flash_Def* obj, uint64_t page_addr, uint8_t* data_buf, size_t data_len);
// 读取连续地址，不要超过4K，也就是0x1000
rt_err_t W25q_Read(Flash_Def* obj, uint64_t page_addr, uint8_t* data_buf, size_t data_len);
// 按字节写入。暂时没做切页，非对齐操作，不建议使用。
rt_err_t W25q_Write_Pages(Flash_Def* obj, uint64_t page_addr, uint8_t* data_buf, size_t data_len);
// 连续写入
rt_err_t W25q_Write_Continuous(Flash_Def* obj, uint64_t start_addr, uint8_t* data_buf, size_t data_len);
rt_err_t W25q_Read_Uid(Flash_Def* obj, uint8_t *res_buf);
// 读状态寄存器
rt_err_t W25q_Read_SRX(Flash_Def* obj);
// 更新寄存器SR1状态。最好启动了硬件写保护使用。否则光读SR寄存器就要判断很多写保护状态s
rt_err_t W25q_Read_SR1(Flash_Def *obj);
// 查询动作是否完成。返回RT_EOK则正常。RT_EBUSY则忙碌。其余为错误。暂时不知道为啥不管用。先用延迟代替一下
// 注意，即使是读寄存器也需要解除写保护
rt_err_t W25q_Check_Busy(Flash_Def* obj);
// 查询写保护是否关闭。返回RT_EOK则已关闭。RT_EBUSY则忙碌。其余为错误
// 注意，即使是读寄存器也需要解除写保护
rt_err_t W25q_Check_Write_Enable(Flash_Def *obj);
// 查询写保护是否打开。返回RT_EOK则已打开。RT_EBUSY则忙碌。其余为错误
// 注意，即使是读寄存器也需要解除写保护
// 这里是为了检查写入置位是否完成
rt_err_t W25q_Check_Write_Disable(Flash_Def *obj);

#endif /* __FLASH_MODULE_H__ */

/*eof*/
